package com.example.prom;

import io.github.bonigarcia.wdm.WebDriverManager;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.JavascriptExecutor;

import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class AdvancedWebCrawler {
    public static void main(String[] args) {
        // 设置WebDriverManager
        WebDriverManager.chromedriver().setup();

        // 配置Chrome选项
        ChromeOptions options = new ChromeOptions();
        configureAntiDetection(options);

        // 创建WebDriver实例
        WebDriver driver = new ChromeDriver(options);

        try {
            // 访问目标网页
            driver.get("https://www.chictr.org.cn/searchproj.html?title=失眠&page=1");

            // 等待页面完全加载
            waitForPageLoad(driver);

            // 检查是否有iframe并处理
//            handleIframes(driver);

            // 获取页面内容（多种方法尝试）
            Document doc = getPageContent(driver);

            // 如果body为空，尝试其他方法
            if (doc.body().children().isEmpty()) {
                System.out.println("Body为空，尝试备用方法...");
                doc = getAlternativeContent(driver);
            }

            // 输出解析结果
            System.out.println("页面标题: " + doc.title());
            System.out.println("Body内容长度: " + doc.body().html().length());
            System.out.println("内容摘要: " + doc.body().text().substring(0, Math.min(200, doc.body().text().length())) + "...");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.quit();
        }
    }

    private static void configureAntiDetection(ChromeOptions options) {
        options.addArguments("--headless=new");
        options.addArguments("--disable-blink-features=AutomationControlled");
        options.addArguments("--disable-infobars");
        options.addArguments("--disable-web-security");
        options.addArguments("--disable-extensions");
        options.addArguments("--disable-gpu");
        options.addArguments("--no-sandbox");
        options.addArguments("--disable-dev-shm-usage");
        options.addArguments("--remote-allow-origins=*");
        options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

        options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
        options.setExperimentalOption("useAutomationExtension", false);

        Map<String, Object> prefs = new HashMap<>();
        prefs.put("credentials_enable_service", false);
        prefs.put("profile.password_manager_enabled", false);
        options.setExperimentalOption("prefs", prefs);
    }

    private static void waitForPageLoad(WebDriver driver) {
        WebDriverWait wait = new WebDriverWait(driver, 30);

        // 等待body标签出现
        wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("body")));

        // 等待特定内容加载
        try {
            wait.until(ExpectedConditions.presenceOfElementLocated(
                    By.cssSelector("pc-wrap")
            ));
        } catch (TimeoutException e) {
            System.out.println("未找到主要内容容器");
        }

        // 等待JavaScript执行完成
        wait.until(webDriver ->
                ((JavascriptExecutor) webDriver).executeScript("return document.readyState")
                        .equals("complete"));
    }

    private static void handleIframes(WebDriver driver) {
        try {
            // 查找所有iframe
            int iframeCount = driver.findElements(By.tagName("iframe")).size();
            System.out.println("发现 " + iframeCount + " 个iframe");

            if (iframeCount > 0) {
                // 切换到第一个iframe
                driver.switchTo().frame(0);
                System.out.println("已切换到iframe");

                // 处理iframe内容...
                // 完成后切回主文档
                driver.switchTo().defaultContent();
            }
        } catch (Exception e) {
            System.out.println("处理iframe时出错: " + e.getMessage());
        }
    }

    private static Document getPageContent(WebDriver driver) {
        try {
            // 方法1：直接获取整个文档
            String pageSource = driver.getPageSource();
            return Jsoup.parse(pageSource);
        } catch (Exception e) {
            System.out.println("方法1失败: " + e.getMessage());
        }

        try {
            // 方法2：通过JavaScript获取完整HTML
            String fullHtml = (String) ((JavascriptExecutor) driver)
                    .executeScript("return document.documentElement.outerHTML");
            return Jsoup.parse(fullHtml);
        } catch (Exception e) {
            System.out.println("方法2失败: " + e.getMessage());
        }

        try {
            // 方法3：直接获取body内容
            WebElement bodyElement = driver.findElement(By.tagName("body"));
            String bodyHtml = bodyElement.getAttribute("innerHTML");
            return Jsoup.parseBodyFragment(bodyHtml);
        } catch (Exception e) {
            System.out.println("方法3失败: " + e.getMessage());
        }

        return Jsoup.parse("<html><body></body></html>");
    }

    private static Document getAlternativeContent(WebDriver driver) {
        try {
            // 方法4：获取特定容器内容
            WebElement container = driver.findElement(By.cssSelector(
                    "div.content, main, article, #main, .container, .content"
            ));
            String containerHtml = container.getAttribute("innerHTML");
            return Jsoup.parse(containerHtml);
        } catch (Exception e) {
            System.out.println("方法4失败: " + e.getMessage());
        }

        try {
            // 方法5：通过JavaScript获取body内容
            String bodyHtml = (String) ((JavascriptExecutor) driver)
                    .executeScript("return document.body.innerHTML");
            return Jsoup.parseBodyFragment(bodyHtml);
        } catch (Exception e) {
            System.out.println("方法5失败: " + e.getMessage());
        }

        try {
            // 方法6：保存页面到文件分析
            String pageSource = driver.getPageSource();
            // 这里可以添加代码将pageSource保存到文件
            return Jsoup.parse(pageSource);
        } catch (Exception e) {
            System.out.println("所有方法均失败");
            return Jsoup.parse("<html><body></body></html>");
        }
    }
}
